#ifndef SMPPSTACK_H
#define SMPPSTACK_H
//
#include <QtCore/qobject.h>
#include <QTcpSocket>
#include <QTcpServer>
#include <QDataStream>
#include <QVector>
#include <QTimer>
#include "smpp.h"


// make a buffer - just a standard vector of chars
typedef QVector<Smpp::Uint8> Buffer;

enum ROLE{Server,Client};


class BaseTestClass
{
	public:
		BaseTestClass();
		virtual ~BaseTestClass();
};

class TestSender:public BaseTestClass
{
public:
	enum STATUS{INIT, SENDMSG, RCVRSP, RCVRECPT, END};
	TestSender(){mState=INIT;}
	~TestSender();
	void result();
	void sendSMMessageReq(){mState=SENDMSG;}
	void processSMResponse(){mState=RCVRSP;}
	void processSMReceiptReq(){mState=RCVRECPT;}
	void sendSMRcptResponse(){mState=END;}
	
	STATUS	 mState;
};


class TestReceiver:public BaseTestClass
{
public:
	enum STATUS{INIT, RCVRSP, END};
	TestReceiver(){mState=INIT;}
	~TestReceiver();
	void result();
	void processSMMessageReq(){mState=INIT;}
	void sendSMMsgResponse(){mState=INIT;}
	void sendSMReceiptReq(){mState=INIT;}
	void processSMResponse(){mState=END;}

	STATUS	 mState;
	QString	destMessageID;
};

class SmppBase : public QObject
{
Q_OBJECT
public:
    explicit SmppBase(ROLE actor=Client, QObject *parent = 0);
    virtual ~SmppBase();
	
Q_SIGNALS:
	void recv(int,QByteArray);
	void breakup();
	void active();
	
public slots:
	virtual void process();
	virtual void sendmsg(QByteArray buff);
//	virtual void sendreceipt();
	virtual void list();
	virtual void doEnquireLink();
//	int delaysend();
	
public:

	void send_enquire_link();
	void read_enquire_link_resp(Buffer &buf);
	
	void read_enquire_link(Buffer &buf);
	void send_enquire_link_resp(Smpp::CommandStatus status, Smpp::Uint32 seqnum);

	bool valid(Smpp::Uint32 command_id, bool isRcvChannel);

//	QTcpSocket *mTcpSocketRecv; //bind receiver
//	QDataStream mDataStreamRecv;
	QTcpSocket *mTcpSocketTrans; //bind transmitter
	QDataStream mDataStreamTrans;
//	bool mTurnRead;
	QTcpServer *mTcpServer;

	QTimer *mTimer_Bind;
	QTimer *mTimer_EnquireLink;
//	QTimer *mTimer_WaitEnquireLinkRsp;

	enum LinkStatus{Ready,Init,Active};
	LinkStatus mStatus;
//	int mLiveCounterR;
	int mLiveCounterT;
	
	ROLE mActor; 
	
//	QDataStream *delayDataStream;
//	char delaybuff[1024];
//	Smpp::Uint32 delaylen;
//	QTimer *delayTimer;
	
	// local functions declarations that send and receive the SMPP PDUs.
	bool read_smpp_pdu(Smpp::Uint32& command_id);
	
	Buffer mRcvBuffer;
	Smpp::Uint32 mBaseSeq;
//	Smpp::Uint32 mBaseMsgId;
//	int messageID;
	char mTempStr[512];
	
	SmppBase *mSmppLink;

};


class SmppClient: public SmppBase
{
Q_OBJECT
public:
	SmppClient(ROLE actor,QObject * parent);
	~SmppClient();

public slots:
	void process();
	void sendmsg(QByteArray buff);
	void doBind();
//	void doEnquireLink();	
	void send_UnbindReq();

private:	

	/*BEGIN!	as client	 */
	void send_BindReq();
	void read_BindRsp(Buffer &buf);
	/*END!	as client	 */

	
	void read_UnbindRsp(Buffer &buf);

};



class SmppServer: public SmppBase
{
Q_OBJECT
public:
	SmppServer(ROLE actor,QObject * parent);
	~SmppServer();

public slots:
	void process();
	void sendmsg(QByteArray buff);
	void waitBind();
//	void doEnquireLink();	
	void send_UnbindReq();

private:	

	/*BEGIN!	as client	 */
        void read_BindReq(Buffer &buf);
        void send_BindRsp(Smpp::CommandStatus status, Smpp::Uint32 seqnum);
	/*END!	as client	 */

	/* send message */
	
	void read_UnbindRsp(Buffer &buf);

};


#endif


